package com.htc.config;

import com.htc.security.AuthProvider;
import com.htc.security.LoginAuthFailHandler;
import com.htc.security.LoginUrlEntryPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * SpringSecurity配置
 *
 * @author: htc
 * @date: Created in 10:49 2018/5/23.
 */
@EnableWebSecurity
@EnableGlobalMethodSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * HTTP权限控制
     *
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置资源访问权限
        http.authorizeRequests()
                //管理员登陆入口
                .antMatchers("/admin/login").permitAll()
                //静态资源
                .antMatchers("/static/**").permitAll()
                //用户登陆入口
                .antMatchers("/user/login").permitAll()
                //管理员访问页面
                .antMatchers("/admin/**").hasRole("ADMIN")
                //用户访问页面
                .antMatchers("/user/**").hasAnyRole("ADMIN", "USER")
                //用户访问的接口
                .antMatchers("/api/user/**").hasAnyRole("ADMIN", "USER")
                .and()
                .formLogin()
                //配置角色登陆处理入口
                .loginProcessingUrl("/login")
                //配置授权失败的处理方法
                .failureHandler(authFailHandler())
                .and()
                //配置登出
                .logout()
                .logoutUrl("/logout")
                //自定义登出页面
                .logoutSuccessUrl("/logout/page")
                //删除cookies
                .deleteCookies("JSESSIONID")
                //使session失效
                .invalidateHttpSession(true)
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(urlEntryPoint())
                .accessDeniedPage("/403");
        //关闭跨域
        http.csrf().disable();
        //启用同源策略
        http.headers().frameOptions().sameOrigin();
//        super.configure(http);
    }

    /**
     * 自定义认证策略
     *
     * @param auth
     * @throws Exception
     */
    @Autowired
    public void configGlobal(AuthenticationManagerBuilder auth) throws Exception {
        //配置内存(H2)的用户名和密码
//        auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN").and();
        auth.authenticationProvider(authProvider())
                //擦除密码
                .eraseCredentials(true);
    }

    /**
     * 自定义认证逻辑
     *
     * @return
     */
    @Bean
    public AuthProvider authProvider() {
        return new AuthProvider();
    }

    @Bean
    public LoginUrlEntryPoint urlEntryPoint() {
        return new LoginUrlEntryPoint("/user/login");
    }

    @Bean
    public LoginAuthFailHandler authFailHandler(){
        return new LoginAuthFailHandler(urlEntryPoint());
    }
}
